#include "app_bt.h"


static int wait_ack(device_t *device){
    usleep(1000 * 50);
    char ack[4];
    read(device->fd, ack, 4);
    if (memcmp(ack, "OK\r\n", 4) == 0)
    {
        log_debug("ack success");
        return 0;
    }
    log_debug("ack error");
    return -1;
}

// 判断蓝牙连接状态
int app_bt_status(device_t *device){
    char *cmd = "AT\r\n";
    write(device->fd, cmd, strlen(cmd));
    return wait_ack(device);
}

// 修改蓝牙名称
int app_bt_rename(device_t *device, char *name){
    char cmd[20];
    sprintf(cmd, "AT+NAME%s\r\n", name);
    write(device->fd, cmd, strlen(cmd));
    return wait_ack(device);
}

// 修改蓝牙波特率
int app_bt_setBaudRate(device_t *device,  BT_BR baudRate){
    char cmd[20];
    sprintf(cmd, "AT+BAUD%c\r\n", baudRate);
    write(device->fd, cmd, strlen(cmd));
    return wait_ack(device);
}

// 重启蓝牙
int app_bt_reset(device_t *device){
    char *cmd = "AT+RESET\r\n";
    write(device->fd, cmd, strlen(cmd));
    return wait_ack(device);
}

// 设置蓝牙的组网ID
int app_bt_setNetId(device_t *device, char *netId){
    char cmd[20];
    sprintf(cmd, "AT+NETID%s\r\n", netId);
    write(device->fd, cmd, strlen(cmd));
    return wait_ack(device);
}

// 设置蓝牙的mac地址
int app_bt_setMaddr(device_t *device, char *maddr){
    char cmd[20];
    sprintf(cmd, "AT+MADDR%s\r\n", maddr);
    write(device->fd, cmd, strlen(cmd));
    return wait_ack(device);
}



static int bt_cofig_init(device_t *device){
    //初始化串口
    app_serial_init(device);

    //设置非阻塞模式
    app_serial_set_block(device, 0);
    app_serial_tclflush(device);

    if (app_bt_status(device) == 0)
    {
        app_bt_setBaudRate(device, BT_BR_115200);
        app_bt_rename(device, "wh_bt");
        app_bt_reset(device);
        usleep(2);
    }
    app_bt_setNetId(device, "7654");
    app_bt_setMaddr(device, "0101");
    // 当前蓝牙的波特率是115200, 而串口是9600, 所以需要修改串口波特率115200
    app_serial_set_baudrate(device,BAUDRATE_115200);
    app_serial_tclflush(device);

    // 再次判断蓝牙是否可用，如果不可用，错误退出，蓝牙初始化失败
    if (app_bt_status(device) != 0) {
        log_error("蓝牙初始化失败");
        return -1;
    }


    // 将串口改阻塞模式
    app_serial_set_block(device, 1);
    app_serial_tclflush(device);

    log_debug("蓝牙初始化成功");
    return 0;
}

int app_bt_init(device_t *device)
{
    device->post_read = app_bt_post_read;
    device->pre_write = app_bt_pre_write;

    return bt_cofig_init(device);
}

/**
 * 从设备读取数据后处理数据来满足网关应用的要求
 * 接收方得到数据（3 + [2]）：f1 dd 07 23 23 ff ff 41 42 43
    f1 dd : 固定的头部
    07： 之后数据的长度（5-16之间） 
    23 23：对端（发送方）的MADDR
    ff ff: 我的MADDR或ffff(群发)
    41 42 43：发送的数据 
 * 处理后的数据格式：conn_type id_len msg_len id msg
 */



static char data_buffer[128];
static int data_len = 0;
static char fix_head[2] = {0xf1, 0xdd};
static void remove_data(int len){
    memmove(data_buffer, data_buffer + len, data_len - len);
    data_len -= len;
}

int app_bt_post_read(char *data, int len)
{
    //先将数据添加到缓冲区
    memcpy(data_buffer + data_len, data, len);
    data_len += len;
    //判断输入的数据是否合法
    if (data_len < 8)
    {
        log_debug("data len error");
        return -1;
    }
    int i = 0;
    //寻找固定头部
    for ( i = 0; i < len; i++){
        if (memcmp(data_buffer + i, fix_head, 2) == 0)
        {
            if (i > 0)
            {
                //如果固定头部不在开头，则将前面的数据丢弃
                remove_data(i);
            }
            //判断数据长度是否合法
            int blue_len = data_buffer[2] + 3;
            if (blue_len > data_len)
            {
                log_debug("data is not complete");
                return 0;
            }
            memset(data, 0, len);
            data[0] = 1;//conn_type
            data[1] = 2;//id_len
            data[2] = data_buffer[2] - 4;//msg_len
            memcpy(data + 3, data_buffer + 3, 2);//id
            memcpy(data + 5, data_buffer + 7, data[2]);//msg
            //移除已经处理的数据
            remove_data(blue_len);
            //返回处理后的数据长度
            return data[2] + 5;
        }
    }
    if(i > 0){
        //删除遍历的无效数据
        log_debug("无效输入");
        remove_data(i);
    }
    return 0;
}


/**
 * 处理将要写入蓝牙数据函数
例子：1 2 3 XX abc
 data: conn_type id_len msg_len id msg
 蓝牙发送数据格式例子：
    41 54 2b 4d 45 53 48 00 ff ff 61 62 63 0d 0a
    41 54 2b 4d 45 53 48 00： AT+MESH（固定头部, 8个字节）
    ff ff: 对端的MADDR（如果是FFFF代表群发）
    61 62 63: 要发送的数据（不超过12字节）
    0d 0a：\r\n（固定结尾）
 */

int app_bt_pre_write(char *data, int len)
{
    //判断输入的数据是否合法
    if (len < 6){
        log_debug("data len error");
        return -1;
    }
    //计算整体需要发送的数据长度
    int ble_len = 8 + 2 + 2 + data[2];

    //构建蓝牙发送数据
    char ble_data[ble_len];
    memcpy(ble_data, "AT+MESH", 8);
    //id
    memcpy(ble_data + 8,data + 3,2);
    //msg
    memcpy(ble_data + 10,data + 5,data[2]);
    //结尾
    memcpy(ble_data + 10 + data[2], "\r\n", 2);
    memset(data, 0, len);
    memcpy(data, ble_data, ble_len);
    return ble_len;
}

